import Dexie from 'dexie';
import "dexie-export-import";

const initDB = (db) => {
    db.version(5).stores({
        profile: "&did, nickName, avatar",
        invitations: "&id, targetId, type, invitor, invitee, status, action, confirmTime, time, invitorNickName, invitorAvatar, inviteeNickName, inviteeAvatar, isRead",
        friends: "&did, nickName, avatar",
        chatlist: "&id, type, name, admin, members, visible",
        chatmessages: "&id, chatId, did, type, message, time, fileName, fileType, isRead, isDelete, nickName, avatar",
        fileData: "&hash, type, buffer, base64",
    });
}
class Database {
    constructor(options) {
        this.db = new Dexie(options.dbName);
        initDB(this.db)
    }

    async saveProfile(self) {
        console.log('DB: save profile')
        await this.db.profile.put(self)
    }

    async getProfile(did) {
        console.log('DB: get profile', did)
        return await this.db.profile.get({ did })
    }

    async cacheFile(hash, type, buffer) {
        console.log('DB: cache file', hash)
        let fileType = "image/jpeg";
        let base64 = `data:${fileType};base64,` + buffer.toString('base64');
        await this.db.fileData.put({ hash, buffer, base64 })
    }

    async getCacheFile(hash) {
        console.log('DB: get cache file', hash)
        return await this.db.fileData.get({ hash })
    }

    async saveInvitation(invitation) {
        console.log('DB: save invitation', invitation)
        await this.db.invitations.put(invitation)
    }

    async markInvitationRead(id) {
        console.log('DB: mark invitation read', id)
        await this.db.invitations.where({ id }).modify({ isRead: true })
    }

    async deleteInvitation(id) {
        console.log('DB: delete invitation', id)
        await this.db.invitations.where({ id }).delete()
    }

    async getInvitation(id) {
        console.log('DB: get invitaiton', id)
        return await this.db.invitations.get({ id })
    }

    async getAllInvitations() {
        console.log('DB: get all invitaitons')
        return await this.db.invitations.toArray()
    }

    async saveFriend(friend) {
        console.log('DB: save friend', friend)
        await this.db.friends.put(friend)
    }

    async getFriend(did) {
        console.log('DB: get friend', did)
        return await this.db.friends.get({ did })
    }

    async deleteFriend(did) {
        console.log('DB: delete friend', did)
        await this.db.friends.where({ did }).delete()
    }

    async getAllFriends() {
        console.log('DB: get all friends')
        return await this.db.friends.toArray()
    }

    async getAllChatList() {
        console.log('DB: get all chat list')
        return await this.db.chatlist.toArray()
    }

    async getChatItem(id) {
        console.log('DB: get chat item', id)
        return await this.db.chatlist.get({ id })
    }

    async saveChatItem(chatItem) {
        console.log('DB: save chat item', chatItem)
        await this.db.chatlist.put(chatItem)
    }

    async deleteChatItem(id) {
        console.log('DB: delete chat item', id)
        await this.db.chatlist.where({ id }).delete()
    }

    async getChatMessages(chatId) {
        console.log('DB: get chat messages', chatId)
        return await this.db.chatmessages.where({ chatId }).reverse().sortBy('time')
    }

    async getLastChatMessage(chatId) {
        console.log('DB: get latest chat message', chatId)
        return await this.db.chatmessages.where({ chatId }).reverse().sortBy('time')
    }

    async searchMessages(chatId, query) {
        console.log('DB: search chat messages', chatId, query)
        return await this.db.chatmessages.filter(item => item.message && item.message.includes(query)).toArray()
    }

    async getChatMessage(id) {
        console.log('DB: get chat message', id)
        return await this.db.chatmessages.get({ id })
    }

    async updateChatMessageProfile(id, profile) {
        console.log('DB: update msg nickName and avatar', profile)
        await this.db.chatmessages.where({ id }).modify({ nickName: profile.nickName, avatar: profile.avatar })
    }

    async saveChatMessage(chatMessage) {
        console.log('DB: add chat message', chatMessage)
        await this.db.chatmessages.put(chatMessage)
    }

    async deleteChatMessage(id) {
        console.log('DB: delete chat message', id)
        await this.db.chatmessages.where({ id }).delete()
    }

    async markRead(id) {
        console.log('DB: mark read', id)
        await this.db.chatmessages.where({ id }).modify({ isRead: true })
    }

    async markDelete(id) {
        console.log('DB: mark delete', id)
        await this.db.chatmessages.where({ id }).modify({ isDelete: true })
    }

    async exportDB() {
        const tables = ['profile', 'invitations', 'friends', 'chatlist', 'chatmessages']
        const blob = await this.db.export({
            prettyJson: true,
            filter: (table, value, key) => {
                return tables.includes(table)
            }
        });
        return blob
    }

    async importDB(blob) {
        await this.db.delete();
        this.db = await Dexie.import(blob, {
            
        });
    }
}

export default Database